package info.rflow.model;

import info.rflow.Utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;


/**
 * @author Holger Brandl
 */
public class RFileParser {


    public static final String HEADER_BLOCK_NAME = "Header";


    public static void main(String[] args) {
        File testFile = new File("testdata/test.R");

        List<RBlock> readBlocks = readBlocks(testFile).getBlocks();
        System.err.println(readBlocks);
    }


    public static RWorkflowModel readBlocks(File rFile) {
        RWorkflowModel wfModel = new RWorkflowModel(rFile);
        if (rFile == null || !rFile.exists()) {
            return wfModel;
        }

        try {
            BufferedReader fileReader = new BufferedReader(new FileReader(rFile));

            String curLine;
            String previousLine = null;
            RBlock curBlock = new RBlock(wfModel, HEADER_BLOCK_NAME);

            while ((curLine = fileReader.readLine()) != null) {
                // process outputs
                if (curLine.startsWith("save")) {
                    String saveFileName = Utils.extractGroup(curLine, ".*, file=[\"](.*)[\"]");
//                    String saveFileName = extractGroup(curLine, ".*, file=[\"][.]?(.*).RData[\"]");
                    curBlock.addOutput(saveFileName);
                }

                // process block inputs
                if (curLine.startsWith("print(load") || curLine.startsWith("load") || curLine.startsWith("# load") || curLine.startsWith("# print(load")) {
                    String inputFileName = Utils.extractGroup(curLine, ".*load[(][\"](.*)[\"][)].*");
                    curBlock.addInput(inputFileName);
                }

                // process new
                if (previousLine != null && previousLine.matches("[#]{10,500}") && curLine.matches("[#]{4,6}[^#]*")) {
                    // add the header block if present
                    if (!curBlock.getCode().isEmpty()) {
                        wfModel.addBlock(curBlock);
                    }

                    // we've found a new block
                    String blockName = Utils.extractGroup(curLine, "[#]{4,6}(.*)").trim();
                    curBlock = new RBlock(wfModel, blockName);
                }

                curBlock.addCodeLine(curLine);

                previousLine = curLine;
            }

            //add  the last block to the buffer
            if (!curBlock.getCode().isEmpty()) {
                wfModel.addBlock(curBlock);
            }


            // set the working directory if present

            String wdFileName = Utils.extractGroup(wfModel.getScript(), "setwd[(]\"(.*)\"[)]");
            if (wdFileName != null && new File(wdFileName).isDirectory()) {
                wfModel.setWorkingDirectory(new File(wdFileName));
            }


            return wfModel;
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }


    public static boolean isUpToDate(RWorkflowModel blockModel) {
        return blockModel.getRFileModTime() == blockModel.getRFile().lastModified();
    }
}
